package com.mca.framework.completableFuture;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: zhoupeng
 * @createTime: 2025年07月07日 21:07:39
 * @version: 1.0
 * @Description:
 * @copyright:
 */
public class AllOfDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        //调api1接口
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            int f1 = new Random().nextInt(100);
            System.out.println("f1 value: " +f1);
            return f1;
        }, executorService);
        //调api2接口
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int f2 = new Random().nextInt(100);
            System.out.println("f2 value:" + f2);
            return f2;
        }, executorService);

        //调api3接口
        CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int f3 = new Random().nextInt(100);
            System.out.println("f3 value：" + f3);
            return f3;
        }, executorService);

        //等后续任务回调处理
        List< CompletableFuture<Integer>> list = new ArrayList<>();
        list.add(future1);
        list.add(future2);
        list.add(future3);
        //可以采用 CompletableFuture.allOf(future1, future2,future3).thenRun(() -> executorService.shutdown()) 这种方式，保证在 future1 和 future2 都完成之后，才去关闭线程池。
        CompletableFuture<Void> all = CompletableFuture.allOf(list.toArray(new CompletableFuture[]{}));
        //等拿到所有线程都执行完返回的结果，然后在进行业务处理
        //业务场景，就是构造一个业务数据，但是需要调用多个接口才能获取到最终数据，就可以使用 CompletableFuture.allOf 按顺序执行
        all.thenRunAsync(()->{
            AtomicInteger atomicInteger=new AtomicInteger();
            list.stream().forEach(future ->{
                try {
                    Integer value = future.get();
                    atomicInteger.updateAndGet(v->v+value);
                    System.out.println(atomicInteger);
                    executorService.shutdown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            });
        },executorService);
    }
    /**
     *     private long getMaxId(Executor executor, String requestId, String maTaskId, String stepId, long maxId, int number, int offset,Long taskEndDate) {
     *         List<MaTaskRequestData> maTaskRequestDataLists = maTaskRequestDataMapper.findAllByTaskIdAndStepIdLimit(maTaskId, stepId, number, offset, maxId);
     *         if(!CollectionUtils.isEmpty(maTaskRequestDataLists)){
     *             //获取最大的maxId
     *             maxId = maTaskRequestDataLists.stream().map(MaTaskRequestData::getId).max(Long::compareTo).get();
     *             //分批次进行异步线程处理，每个批次处理{BatchCommonConstant.BATCH_NUMBER_5000}人数据,多线程处理
     *             List<List<MaTaskRequestData>> MaTaskRequestDatasPartition = Lists.partition(maTaskRequestDataLists, BatchCommonConstant.BATCH_NUMBER_5000);
     *             List<CompletableFuture<Map<String,String>>> futures = new ArrayList<>();  //List< CompletableFuture<Integer>> list = new ArrayList<>();
     *             for (List<MaTaskRequestData> maTaskRequestDataList : MaTaskRequestDatasPartition) {
     * //                MaToScrmCustomerInfoNew(maTaskRequestDataList, requestId, maTaskId, stepId,taskEndDate);
     *                 //开启异步线程处理
     *                 long finalMaxId = maxId;
     *                 CompletableFuture<Map<String,String>> future = CompletableFuture.supplyAsync(() -> {
     *                     // 异步执行
     *                     //明确客户与导购的关系
     *                     //以导购维度进行数据处理，包含同一个导购的客户进行分组，同一个客户进行去重
     *                     return MaToScrmCustomerInfoNew(maTaskRequestDataList, requestId, maTaskId, stepId,taskEndDate);
     *                 }, executor).exceptionally(e -> {
     *                     log.error("maTaskId:{},stepId:{},maxId:{},number:{}异步处理导购关系数据异常！error:{}",maTaskId,stepId, finalMaxId,number, e.getMessage(),e);
     *                     return new HashMap<>();
     *                 });
     *                 futures.add(future); //  list.add(future1); list.add(future2); list.add(future3);
     *             }
     *             CompletableFuture[] array = futures.toArray(new CompletableFuture[0]);
     *             CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(array); // CompletableFuture<Void> all = CompletableFuture.allOf(list.toArray(new CompletableFuture[]{}));
     *             combinedFuture.whenComplete((res, ex) -> {
     *                 if (ex != null) {
     *                     System.out.println("Error occurred: " + ex);
     *                     log.info("maTaskId：{}转换导购关系异步线程异常!",maTaskId,ex);
     *                 }
     *             });
     *             combinedFuture.join(); // 此处会输出错误信息
     *             log.info("maTaskId:{}导购关系全部处理完成",maTaskId);
     *         }
     *         return maxId;
     *     }
     */
}
